const { exec } = require('child_process');
const { promisify } = require('util');
const path = require('path');
const fs = require('fs-extra');
const logManager = require('./logManager');

const execAsync = promisify(exec);

/**
 * Windows环境构建管理器
 * 专门处理Windows环境下的构建兼容性问题
 */
class WindowsBuildManager {
  constructor() {
    this.isWindows = process.platform === 'win32';
  }

  /**
   * 检查Windows环境状态
   */
  async checkWindowsEnvironment() {
    if (!this.isWindows) {
      return { isWindows: false, status: 'not-windows' };
    }

    const status = {
      isWindows: true,
      docker: false,
      node: false,
      npm: false,
      git: false,
      issues: []
    };

    // 检查Docker
    try {
      await execAsync('docker --version', { timeout: 5000 });
      await execAsync('docker info', { timeout: 10000 });
      status.docker = true;
    } catch (error) {
      status.issues.push('Docker Desktop未运行或配置有问题');
    }

    // 检查Node.js
    try {
      const { stdout } = await execAsync('node --version');
      status.node = stdout.trim();
    } catch (error) {
      status.issues.push('Node.js未安装');
    }

    // 检查npm
    try {
      const { stdout } = await execAsync('npm --version');
      status.npm = stdout.trim();
    } catch (error) {
      status.issues.push('npm不可用');
    }

    // 检查Git
    try {
      await execAsync('git --version');
      status.git = true;
    } catch (error) {
      status.issues.push('Git未安装');
    }

    return status;
  }

  /**
   * Windows环境下的构建策略选择
   */
  async selectBuildStrategy(projectPath, nodeVersion, buildOptions = {}) {
    const envStatus = await this.checkWindowsEnvironment();
    
    if (!envStatus.isWindows) {
      return { strategy: 'auto', reason: '非Windows环境' };
    }

    // 如果Docker可用，优先使用Docker
    if (envStatus.docker) {
      return { 
        strategy: 'docker-windows', 
        reason: 'Windows Docker环境可用',
        optimizations: [
          'use-china-mirror',
          'network-optimization',
          'build-cache'
        ]
      };
    }

    // Docker不可用，检查本地Node环境
    if (envStatus.node && envStatus.npm) {
      const nodeVersionMatch = this.checkNodeVersionCompatibility(envStatus.node, nodeVersion);
      
      if (nodeVersionMatch.compatible) {
        return {
          strategy: 'local-windows',
          reason: `本地Node版本兼容 (${envStatus.node})`,
          optimizations: [
            'use-china-npm-mirror',
            'node-sass-binary-mirror',
            'skip-optional-deps'
          ]
        };
      } else {
        return {
          strategy: 'nvm-windows',
          reason: `需要切换Node版本 (当前: ${envStatus.node}, 需要: ${nodeVersion})`,
          optimizations: [
            'install-target-node-version',
            'use-china-npm-mirror'
          ]
        };
      }
    }

    return {
      strategy: 'error',
      reason: 'Windows环境缺少必要工具',
      issues: envStatus.issues,
      suggestions: [
        '安装Node.js: https://nodejs.org/',
        '安装Git: https://git-scm.com/',
        '安装Docker Desktop: https://www.docker.com/products/docker-desktop'
      ]
    };
  }

  /**
   * 检查Node版本兼容性
   */
  checkNodeVersionCompatibility(currentVersion, targetVersion) {
    // 简化版本比较逻辑
    const current = this.parseNodeVersion(currentVersion);
    const target = this.parseNodeVersion(targetVersion);

    // 主版本号匹配即认为兼容
    const compatible = current.major === target.major;

    return {
      compatible,
      current: current.version,
      target: target.version,
      reason: compatible ? '主版本号匹配' : `版本不匹配: ${current.major} vs ${target.major}`
    };
  }

  /**
   * 解析Node版本号
   */
  parseNodeVersion(versionStr) {
    // 处理 "node14" 格式
    if (versionStr.startsWith('node')) {
      const major = parseInt(versionStr.replace('node', ''));
      return { major, version: `${major}.x.x` };
    }

    // 处理 "v14.21.3" 格式
    const match = versionStr.match(/v?(\d+)\.(\d+)\.(\d+)/);
    if (match) {
      return {
        major: parseInt(match[1]),
        minor: parseInt(match[2]),
        patch: parseInt(match[3]),
        version: `${match[1]}.${match[2]}.${match[3]}`
      };
    }

    return { major: 0, version: 'unknown' };
  }

  /**
   * Windows环境下的本地构建
   */
  async buildWithLocalWindows(projectPath, nodeVersion, envVars = {}, platform = 'h5', projectId = null, apiUrl = null) {
    try {
      if (projectId) {
        logManager.sendBuildStep(projectId, 'Windows本地构建', '使用本地Node.js环境构建');
      }

      // 配置Windows环境变量
      const windowsEnv = {
        ...process.env,
        ...envVars,
        // Windows特有的环境变量
        npm_config_registry: 'https://registry.npmmirror.com/',
        npm_config_sass_binary_site: 'https://npmmirror.com/mirrors/node-sass/',
        npm_config_phantomjs_cdnurl: 'https://npmmirror.com/mirrors/phantomjs/',
        npm_config_electron_mirror: 'https://npmmirror.com/mirrors/electron/',
        // 网络超时配置
        npm_config_fetch_timeout: '60000',
        npm_config_fetch_retry_mintimeout: '20000',
        npm_config_fetch_retry_maxtimeout: '120000',
        npm_config_fetch_retries: '3'
      };

      // 安装依赖
      if (projectId) {
        logManager.sendBuildStep(projectId, '依赖安装', '使用国内镜像源安装项目依赖');
      }

      const installCommand = 'npm install --registry=https://registry.npmmirror.com/ --legacy-peer-deps';
      await execAsync(installCommand, {
        cwd: projectPath,
        env: windowsEnv,
        timeout: 600000 // 10分钟超时
      });

      // 构建项目
      const buildCommand = await this.getBuildCommand(projectPath, platform, apiUrl);
      
      if (projectId) {
        logManager.sendBuildStep(projectId, '项目构建', `执行构建命令: ${buildCommand}`);
      }

      const { stdout, stderr } = await execAsync(buildCommand, {
        cwd: projectPath,
        env: windowsEnv,
        timeout: 1800000 // 30分钟超时
      });

      return {
        success: true,
        outputDir: 'dist',
        buildMethod: 'local-windows',
        stdout: stdout.slice(-2000),
        stderr: stderr ? stderr.slice(-1000) : null
      };

    } catch (error) {
      throw new Error(`Windows本地构建失败: ${error.message}`);
    }
  }

  /**
   * 获取构建命令
   */
  async getBuildCommand(projectPath, platform, apiUrl) {
    const packagePath = path.join(projectPath, 'package.json');
    let buildCommand = 'npm run build';

    if (await fs.pathExists(packagePath)) {
      const pkg = await fs.readJson(packagePath);
      
      // 根据平台选择构建命令
      const platformCommands = {
        'h5': 'build:h5',
        'mp-weixin': 'build:mp-weixin',
        'mp-alipay': 'build:mp-alipay'
      };
      
      const buildScript = platformCommands[platform] || 'build';
      
      if (pkg.scripts && pkg.scripts[buildScript]) {
        buildCommand = `npm run ${buildScript}`;
      }
    }

    // 添加API URL参数
    if (apiUrl) {
      buildCommand += ` --apiurl=${apiUrl}`;
    }

    return buildCommand;
  }

  /**
   * Windows环境诊断和修复建议
   */
  async diagnoseAndSuggest(projectPath) {
    const envStatus = await this.checkWindowsEnvironment();
    const suggestions = [];

    if (!envStatus.isWindows) {
      return { applicable: false };
    }

    suggestions.push('=== Windows环境诊断报告 ===');

    // Docker检查
    if (!envStatus.docker) {
      suggestions.push('❌ Docker问题:');
      suggestions.push('   1. 确保Docker Desktop已安装并启动');
      suggestions.push('   2. 切换到Linux容器模式');
      suggestions.push('   3. 运行: setup-windows-docker.bat');
      suggestions.push('');
    } else {
      suggestions.push('✅ Docker环境正常');
    }

    // Node.js检查
    if (!envStatus.node) {
      suggestions.push('❌ Node.js未安装');
      suggestions.push('   下载安装: https://nodejs.org/');
    } else {
      suggestions.push(`✅ Node.js: ${envStatus.node}`);
    }

    // npm检查
    if (!envStatus.npm) {
      suggestions.push('❌ npm不可用');
    } else {
      suggestions.push(`✅ npm: ${envStatus.npm}`);
    }

    // 网络优化建议
    suggestions.push('');
    suggestions.push('💡 网络优化建议:');
    suggestions.push('   1. 配置npm国内镜像源');
    suggestions.push('   2. 配置Docker国内镜像源');
    suggestions.push('   3. 如在企业网络，配置代理设置');

    return {
      applicable: true,
      status: envStatus,
      suggestions: suggestions.join('\n')
    };
  }
}

module.exports = new WindowsBuildManager();
